//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Data;
using DotNetNuke.Entities.Modules.Definitions;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Services.EventQueue;
using DotNetNuke.Services.Installer.Packages;

namespace DotNetNuke.Entities.Modules
{
	public class DesktopModuleController
	{
		private static DataProvider dataProvider = DataProvider.Instance();
		private static object GetDesktopModulesByPortalCallBack(CacheItemArgs cacheItemArgs)
		{
			int portalId = (int)cacheItemArgs.ParamList[0];
			return CBO.FillDictionary<int, DesktopModuleInfo>("DesktopModuleID", dataProvider.GetDesktopModulesByPortal(portalId), new Dictionary<int, DesktopModuleInfo>());
		}
		private static object GetPortalDesktopModulesByPortalIDCallBack(CacheItemArgs cacheItemArgs)
		{
			int portalId = (int)cacheItemArgs.ParamList[0];
			return CBO.FillDictionary<int, PortalDesktopModuleInfo>("PortalDesktopModuleID", DataProvider.Instance().GetPortalDesktopModules(portalId, Null.NullInteger), new Dictionary<int, PortalDesktopModuleInfo>());
		}
		public static int AddDesktopModuleToPortal(int portalID, DesktopModuleInfo desktopModule, DesktopModulePermissionCollection permissions, bool clearCache)
		{
			int portalDesktopModuleID = AddDesktopModuleToPortal(portalID, desktopModule.DesktopModuleID, false, clearCache);
			if (portalDesktopModuleID > Null.NullInteger) {
				DesktopModulePermissionController.DeleteDesktopModulePermissionsByPortalDesktopModuleID(portalDesktopModuleID);
				foreach (DesktopModulePermissionInfo permission in permissions) {
					permission.PortalDesktopModuleID = portalDesktopModuleID;
					DesktopModulePermissionController.AddDesktopModulePermission(permission);
				}
			}
			return portalDesktopModuleID;
		}
		public static int AddDesktopModuleToPortal(int portalID, int desktopModuleID, bool addPermissions, bool clearCache)
		{
			int portalDesktopModuleID = Null.NullInteger;
			PortalDesktopModuleInfo portalDesktopModule = GetPortalDesktopModule(portalID, desktopModuleID);
			if (portalDesktopModule == null) {
				portalDesktopModuleID = DataProvider.Instance().AddPortalDesktopModule(portalID, desktopModuleID, UserController.GetCurrentUserInfo().UserID);
				Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
				objEventLog.AddLog("PortalDesktopModuleID", portalDesktopModuleID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.PORTALDESKTOPMODULE_CREATED);
				if (addPermissions) {
					ArrayList permissions = PermissionController.GetPermissionsByPortalDesktopModule();
					if (permissions.Count > 0) {
						PermissionInfo permission = permissions[0] as PermissionInfo;
						PortalInfo objPortal = new PortalController().GetPortal(portalID);
						if (permission != null && objPortal != null) {
							DesktopModulePermissionInfo desktopModulePermission = new DesktopModulePermissionInfo(permission);
							desktopModulePermission.RoleID = objPortal.AdministratorRoleId;
							desktopModulePermission.AllowAccess = true;
							desktopModulePermission.PortalDesktopModuleID = portalDesktopModuleID;
							DesktopModulePermissionController.AddDesktopModulePermission(desktopModulePermission);
						}
					}
				}
			} else {
				portalDesktopModuleID = portalDesktopModule.PortalDesktopModuleID;
			}
			if (clearCache) {
				DataCache.ClearPortalCache(portalID, true);
			}
			return portalDesktopModuleID;
		}
		public static void AddDesktopModuleToPortals(int desktopModuleID)
		{
			PortalController controller = new PortalController();
			foreach (PortalInfo portal in controller.GetPortals()) {
				AddDesktopModuleToPortal(portal.PortalID, desktopModuleID, true, false);
			}
			DataCache.ClearHostCache(true);
		}
		public static void AddDesktopModulesToPortal(int portalID)
		{
			foreach (DesktopModuleInfo desktopModule in DesktopModuleController.GetDesktopModules(Null.NullInteger).Values) {
				if (!desktopModule.IsPremium) {
					AddDesktopModuleToPortal(portalID, desktopModule.DesktopModuleID, !desktopModule.IsAdmin, false);
				}
			}
			DataCache.ClearPortalCache(portalID, true);
		}
		public static void DeleteDesktopModule(string moduleName)
		{
			DesktopModuleInfo desktopModule = GetDesktopModuleByModuleName(moduleName, Null.NullInteger);
			if (desktopModule != null) {
				DesktopModuleController controller = new DesktopModuleController();
				controller.DeleteDesktopModule(desktopModule.DesktopModuleID);
				PackageController.DeletePackage(desktopModule.PackageID);
			}
		}
		public static DesktopModuleInfo GetDesktopModule(int desktopModuleID, int portalID)
		{
			DesktopModuleInfo desktopModule = null;
			Dictionary<int, DesktopModuleInfo> desktopModules = GetDesktopModules(portalID);
			if (!desktopModules.TryGetValue(desktopModuleID, out desktopModule)) {
				desktopModule = CBO.FillObject<DesktopModuleInfo>(dataProvider.GetDesktopModule(desktopModuleID));
			}
			return desktopModule;
		}
		public static DesktopModuleInfo GetDesktopModuleByPackageID(int packageID)
		{
			return CBO.FillObject<DesktopModuleInfo>(dataProvider.GetDesktopModuleByPackageID(packageID));
		}
		public static DesktopModuleInfo GetDesktopModuleByModuleName(string moduleName, int portalID)
		{
			DesktopModuleInfo desktopModule = null;
			foreach (KeyValuePair<int, DesktopModuleInfo> kvp in GetDesktopModules(portalID)) {
				if (kvp.Value.ModuleName == moduleName) {
					desktopModule = kvp.Value;
					break;
				}
			}
			if (desktopModule == null) {
				desktopModule = CBO.FillObject<DesktopModuleInfo>(dataProvider.GetDesktopModuleByModuleName(moduleName));
			}
			return desktopModule;
		}
		public static Dictionary<int, DesktopModuleInfo> GetDesktopModules(int portalID)
		{
			Dictionary<int, DesktopModuleInfo> desktopModules = new Dictionary<int, DesktopModuleInfo>();
			if (portalID == Null.NullInteger) {
				desktopModules = CBO.FillDictionary<int, DesktopModuleInfo>("DesktopModuleID", dataProvider.GetDesktopModules(), new Dictionary<int, DesktopModuleInfo>());
			} else {
				string cacheKey = string.Format(DataCache.DesktopModuleCacheKey, portalID.ToString());
				desktopModules = CBO.GetCachedObject<Dictionary<int, DesktopModuleInfo>>(new CacheItemArgs(cacheKey, DataCache.DesktopModuleCacheTimeOut, DataCache.DesktopModuleCachePriority, portalID), GetDesktopModulesByPortalCallBack);
			}
			return desktopModules;
		}
		public static PortalDesktopModuleInfo GetPortalDesktopModule(int portalID, int desktopModuleID)
		{
			return CBO.FillObject<PortalDesktopModuleInfo>(DataProvider.Instance().GetPortalDesktopModules(portalID, desktopModuleID));
		}
		public static DesktopModuleInfo GetDesktopModuleByFriendlyName(string friendlyName)
		{
			DesktopModuleInfo desktopModule = null;
			foreach (KeyValuePair<int, DesktopModuleInfo> kvp in GetDesktopModules(Null.NullInteger)) {
				if (kvp.Value.FriendlyName == friendlyName) {
					desktopModule = kvp.Value;
					break;
				}
			}
			return desktopModule;
		}
		public static Dictionary<int, PortalDesktopModuleInfo> GetPortalDesktopModulesByDesktopModuleID(int desktopModuleID)
		{
			return CBO.FillDictionary<int, PortalDesktopModuleInfo>("PortalDesktopModuleID", DataProvider.Instance().GetPortalDesktopModules(Null.NullInteger, desktopModuleID));
		}
		public static Dictionary<int, PortalDesktopModuleInfo> GetPortalDesktopModulesByPortalID(int portalID)
		{
			string cacheKey = string.Format(DataCache.PortalDesktopModuleCacheKey, portalID.ToString());
			return CBO.GetCachedObject<Dictionary<int, PortalDesktopModuleInfo>>(new CacheItemArgs(cacheKey, DataCache.PortalDesktopModuleCacheTimeOut, DataCache.PortalDesktopModuleCachePriority, portalID), GetPortalDesktopModulesByPortalIDCallBack);
		}
		public static SortedList<string, PortalDesktopModuleInfo> GetPortalDesktopModules(int portalID)
		{
			Dictionary<int, PortalDesktopModuleInfo> dicModules = GetPortalDesktopModulesByPortalID(portalID);
			SortedList<string, PortalDesktopModuleInfo> lstModules = new SortedList<string, PortalDesktopModuleInfo>();
			foreach (PortalDesktopModuleInfo desktopModule in dicModules.Values) {
				if (DesktopModulePermissionController.HasDesktopModulePermission(desktopModule.Permissions, "DEPLOY")) {
					lstModules.Add(desktopModule.FriendlyName, desktopModule);
				}
			}
			return lstModules;
		}
		public static void RemoveDesktopModuleFromPortal(int portalID, int desktopModuleID, bool clearCache)
		{
			DataProvider.Instance().DeletePortalDesktopModules(portalID, desktopModuleID);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("DesktopModuleID", desktopModuleID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.PORTALDESKTOPMODULE_DELETED);
			if (clearCache) {
				DataCache.ClearPortalCache(portalID, false);
			}
		}
		public static void RemoveDesktopModuleFromPortals(int desktopModuleID)
		{
			DataProvider.Instance().DeletePortalDesktopModules(Null.NullInteger, desktopModuleID);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("DesktopModuleID", desktopModuleID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.PORTALDESKTOPMODULE_DELETED);
			DataCache.ClearHostCache(true);
		}
		public static void RemoveDesktopModulesFromPortal(int portalID)
		{
			DataProvider.Instance().DeletePortalDesktopModules(portalID, Null.NullInteger);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("PortalID", portalID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.PORTALDESKTOPMODULE_DELETED);
			DataCache.ClearPortalCache(portalID, true);
		}
		public static int SaveDesktopModule(DesktopModuleInfo desktopModule, bool saveChildren, bool clearCache)
		{
			int desktopModuleID = desktopModule.DesktopModuleID;
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			if (desktopModuleID == Null.NullInteger) {
				desktopModuleID = dataProvider.AddDesktopModule(desktopModule.PackageID, desktopModule.ModuleName, desktopModule.FolderName, desktopModule.FriendlyName, desktopModule.Description, desktopModule.Version, desktopModule.IsPremium, desktopModule.IsAdmin, desktopModule.BusinessControllerClass, desktopModule.SupportedFeatures,
				desktopModule.CompatibleVersions, desktopModule.Dependencies, desktopModule.Permissions, UserController.GetCurrentUserInfo().UserID);
				objEventLog.AddLog(desktopModule, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, "", DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.DESKTOPMODULE_CREATED);
			} else {
				dataProvider.UpdateDesktopModule(desktopModule.DesktopModuleID, desktopModule.PackageID, desktopModule.ModuleName, desktopModule.FolderName, desktopModule.FriendlyName, desktopModule.Description, desktopModule.Version, desktopModule.IsPremium, desktopModule.IsAdmin, desktopModule.BusinessControllerClass,
				desktopModule.SupportedFeatures, desktopModule.CompatibleVersions, desktopModule.Dependencies, desktopModule.Permissions, UserController.GetCurrentUserInfo().UserID);
				objEventLog.AddLog(desktopModule, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, "", DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.DESKTOPMODULE_UPDATED);
			}
			if (saveChildren) {
				foreach (ModuleDefinitionInfo definition in desktopModule.ModuleDefinitions.Values) {
					definition.DesktopModuleID = desktopModuleID;
					ModuleDefinitionInfo moduleDefinition = ModuleDefinitionController.GetModuleDefinitionByFriendlyName(definition.FriendlyName, desktopModuleID);
					if (moduleDefinition != null) {
						definition.ModuleDefID = moduleDefinition.ModuleDefID;
					}
					ModuleDefinitionController.SaveModuleDefinition(definition, saveChildren, clearCache);
				}
			}
			if (clearCache) {
				DataCache.ClearHostCache(true);
			}
			return desktopModuleID;
		}
		public static void SerializePortalDesktopModules(XmlWriter writer, int portalID)
		{
			writer.WriteStartElement("portalDesktopModules");
			foreach (PortalDesktopModuleInfo portalDesktopModule in GetPortalDesktopModulesByPortalID(portalID).Values) {
				writer.WriteStartElement("portalDesktopModule");
				writer.WriteElementString("friendlyname", portalDesktopModule.FriendlyName);
				writer.WriteStartElement("portalDesktopModulePermissions");
				foreach (DesktopModulePermissionInfo permission in portalDesktopModule.Permissions) {
					writer.WriteStartElement("portalDesktopModulePermission");
					writer.WriteElementString("permissioncode", permission.PermissionCode);
					writer.WriteElementString("permissionkey", permission.PermissionKey);
					writer.WriteElementString("allowaccess", permission.AllowAccess.ToString().ToLower());
					writer.WriteElementString("rolename", permission.RoleName);
					writer.WriteEndElement();
				}
				writer.WriteEndElement();
				writer.WriteEndElement();
			}
			writer.WriteEndElement();
		}
		public int AddDesktopModule(DesktopModuleInfo objDesktopModule)
		{
			return SaveDesktopModule(objDesktopModule, false, true);
		}
		public void DeleteDesktopModule(DesktopModuleInfo objDesktopModule)
		{
			dataProvider.DeleteDesktopModule(objDesktopModule.DesktopModuleID);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog(objDesktopModule, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, "", DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.DESKTOPMODULE_DELETED);
			DataCache.ClearHostCache(true);
		}
		public void DeleteDesktopModule(int desktopModuleID)
		{
			dataProvider.DeleteDesktopModule(desktopModuleID);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("DesktopModuleID", desktopModuleID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.DESKTOPMODULE_DELETED);
			DataCache.ClearHostCache(true);
		}
		public void UpdateDesktopModule(DesktopModuleInfo objDesktopModule)
		{
			SaveDesktopModule(objDesktopModule, false, true);
		}
		public void UpdateModuleInterfaces(ref DesktopModuleInfo desktopModuleInfo)
		{
			if ((UserController.GetCurrentUserInfo() == null)) {
				UpdateModuleInterfaces(ref desktopModuleInfo, "", true);
			} else {
				UpdateModuleInterfaces(ref desktopModuleInfo, UserController.GetCurrentUserInfo().Username, true);
			}
		}
		public void UpdateModuleInterfaces(ref DesktopModuleInfo desktopModuleInfo, string sender, bool forceAppRestart)
		{
			DotNetNuke.Services.EventQueue.EventMessage oAppStartMessage = new DotNetNuke.Services.EventQueue.EventMessage();
			oAppStartMessage.Sender = sender;
			oAppStartMessage.Priority = MessagePriority.High;
			oAppStartMessage.ExpirationDate = DateTime.Now.AddYears(-1);
			oAppStartMessage.SentDate = System.DateTime.Now;
			oAppStartMessage.Body = "";
			oAppStartMessage.ProcessorType = "DotNetNuke.Entities.Modules.EventMessageProcessor, DotNetNuke";
			oAppStartMessage.ProcessorCommand = "UpdateSupportedFeatures";
			oAppStartMessage.Attributes.Add("BusinessControllerClass", desktopModuleInfo.BusinessControllerClass);
			oAppStartMessage.Attributes.Add("DesktopModuleId", desktopModuleInfo.DesktopModuleID.ToString());
			EventQueueController.SendMessage(oAppStartMessage, "Application_Start");
			if ((forceAppRestart)) {
				DotNetNuke.Common.Utilities.Config.Touch();
			}
		}

		#region "Obsolete"

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method AddDesktopModuleToPortal(Integer, Integer)")]
		public void AddPortalDesktopModule(int portalID, int desktopModuleID)
		{
			DataProvider.Instance().AddPortalDesktopModule(portalID, desktopModuleID, UserController.GetCurrentUserInfo().UserID);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("DesktopModuleID", desktopModuleID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.PORTALDESKTOPMODULE_CREATED);
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method RemoveDesktopModulesFromPortal(Integer)")]
		public void DeletePortalDesktopModules(int PortalID, int desktopModuleID)
		{
			DataProvider.Instance().DeletePortalDesktopModules(PortalID, desktopModuleID);
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("DesktopModuleID", desktopModuleID.ToString(), PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.PORTALDESKTOPMODULE_DELETED);
			DataCache.ClearPortalCache(PortalID, true);
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method GetDesktopModule(Integer, Integer)")]
		public DesktopModuleInfo GetDesktopModule(int desktopModuleId)
		{
			return CBO.FillObject<DesktopModuleInfo>(dataProvider.GetDesktopModule(desktopModuleId));
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method GetDesktopModuleByModuleName(String, Integer)")]
		public DesktopModuleInfo GetDesktopModuleByName(string FriendlyName)
		{
			return (DesktopModuleInfo)CBO.FillObject(DataProvider.Instance().GetDesktopModuleByFriendlyName(FriendlyName), typeof(DesktopModuleInfo));
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method GetDesktopModuleByModuleName(String, Integer)")]
		public DesktopModuleInfo GetDesktopModuleByModuleName(string moduleName)
		{
			return CBO.FillObject<DesktopModuleInfo>(dataProvider.GetDesktopModuleByModuleName(moduleName));
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method GetDesktopModules(Integer)")]
		public ArrayList GetDesktopModules()
		{
			return CBO.FillCollection(dataProvider.GetDesktopModules(), typeof(DesktopModuleInfo));
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method GetDesktopModules(Integer)")]
		public ArrayList GetDesktopModulesByPortal(int portalID)
		{
			return CBO.FillCollection(dataProvider.GetDesktopModulesByPortal(portalID), typeof(DesktopModuleInfo));
		}

		[Obsolete("This method replaced in DotNetNuke 5.0 by Shared method GetPortalDesktopModulesByPortalID(Integer) and GetPortalDesktopModulesByDesktopModuleID(Integer) And GetPortalDesktopModule(Integer, Integer)")]
		public ArrayList GetPortalDesktopModules(int portalID, int desktopModuleID)
		{
			return CBO.FillCollection(DataProvider.Instance().GetPortalDesktopModules(portalID, desktopModuleID), typeof(PortalDesktopModuleInfo));
		}


		#endregion
	}
}
